"use client"

import { useEffect, useState, useRef,useCallback } from "react"
import type { Database } from "@/lib/database.types"

type AnonymousUser = Database["public"]["Tables"]["anonymous_users"]["Row"]

interface OnlineUserEntry {
  id: string
  nickname: string
  avatar_seed?: string
  lastSeen: number
}

// Constants
const ONLINE_USERS_STORAGE_KEY = "onlineUsers"
const USER_TIMEOUT_MS = 60000 // Consider users offline after 1 minute of inactivity
const LOCAL_STORAGE_CHECK_INTERVAL = 1000 // Check every second

export default function OnlineUsers() {
  const [users, setUsers] = useState<OnlineUserEntry[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const intervalRef = useRef<NodeJS.Timeout | null>(null)

  // Function to get online users from localStorage
  const getOnlineUsersFromStorage = () => {
    try {
      const onlineUsersStr = localStorage.getItem(ONLINE_USERS_STORAGE_KEY)
      if (!onlineUsersStr) {
        console.log("[OnlineUsers] No users found in localStorage")
        return []
      }

      try {
        const onlineUsersObj = JSON.parse(onlineUsersStr)
        const currentTime = Date.now()
        const userEntries: OnlineUserEntry[] = []

        console.log('[OnlineUsers] Raw online users data:', onlineUsersObj);

        // Filter out users who haven't been seen recently
        for (const [userId, userData] of Object.entries(onlineUsersObj)) {
          if (!userId || !userData) continue; // Skip invalid entries
          
          const typedUserData = userData as {
            nickname: string
            lastSeen: number
          }

          // Provide defaults if data is corrupted
          const nickname = typedUserData.nickname || `User-${userId.substring(0, 5)}`;
          const lastSeen = typedUserData.lastSeen || Date.now();

          // Only include users who have been seen in the last minute
          if (currentTime - lastSeen < USER_TIMEOUT_MS) {
            userEntries.push({
              id: userId,
              nickname: nickname,
              avatar_seed: userId, // Use userId as avatar seed if none provided
              lastSeen: lastSeen,
            })
          } else {
            console.log(`[OnlineUsers] User ${nickname} (${userId}) timed out - last seen ${(currentTime - lastSeen)/1000}s ago`);
          }
        }

        console.log(`[OnlineUsers] Found ${userEntries.length} active users:`, 
          userEntries.map(u => `${u.nickname} (${u.id.substring(0, 8)})`));
        return userEntries
      } catch (parseError) {
        console.error("[OnlineUsers] Failed to parse online users JSON", parseError)
        // Reset the localStorage if JSON is invalid
        localStorage.setItem(ONLINE_USERS_STORAGE_KEY, "{}")
        return []
      }
    } catch (e) {
      console.error("[OnlineUsers] Error accessing localStorage", e)
      return []
    }
  }

  // Function to check and update online users
  const updateOnlineUsers = () => {
    try {
      const onlineUsers = getOnlineUsersFromStorage()
      console.log('[OnlineUsers] updateOnlineUsers called, found', onlineUsers.length, 'users');
      
      // Force an update to the state even if the array looks the same
      // This ensures the component re-renders with the latest data
      setUsers(prevUsers => {
        // Compare if users are different
        if (JSON.stringify(prevUsers) !== JSON.stringify(onlineUsers)) {
          console.log('[OnlineUsers] Users list changed, updating state');
          return onlineUsers;
        }
        
        // If the lengths are different, definitely update
        if (prevUsers.length !== onlineUsers.length) {
          console.log('[OnlineUsers] Number of users changed, updating state');
          return onlineUsers;
        }
        
        // If the timestamps have changed, update
        const timeChanged = onlineUsers.some((newUser) => {
          const prevUser = prevUsers.find(p => p.id === newUser.id);
          return !prevUser || prevUser.lastSeen !== newUser.lastSeen;
        });
        
        if (timeChanged) {
          console.log('[OnlineUsers] User activity changed, updating state');
          return onlineUsers;
        }
        
        console.log('[OnlineUsers] No changes detected');
        return prevUsers;
      });
      
      setLoading(false)
    } catch (e) {
      console.error('[OnlineUsers] Error in updateOnlineUsers:', e);
      setLoading(false);
    }
  }

  // Function to handle custom events from RetroChat component
  const handleUserChange = (event: CustomEvent) => {
    console.log('[OnlineUsers] Received user change event:', event.detail);
    
    // Force an immediate update of the users list
    updateOnlineUsers();
    
    // Then update again after a short delay to catch any delayed localStorage updates
    setTimeout(updateOnlineUsers, 500);
  }

  // Test function to add a mock user (for debugging)
  const addMockUser = () => {
    try {
      const onlineUsersStr = localStorage.getItem(ONLINE_USERS_STORAGE_KEY)
      let onlineUsers: Record<string, {nickname: string, lastSeen: number}> = {}
      
      if (onlineUsersStr) {
        try {
          onlineUsers = JSON.parse(onlineUsersStr)
        } catch (e) {
          onlineUsers = {}
        }
      }
      
      const mockId = `mock-${Date.now()}`
      onlineUsers[mockId] = {
        nickname: `TestUser-${Math.floor(Math.random() * 100)}`,
        lastSeen: Date.now()
      }
      
      localStorage.setItem(ONLINE_USERS_STORAGE_KEY, JSON.stringify(onlineUsers))
      console.log("[OnlineUsers] Added mock user", onlineUsers[mockId])
      updateOnlineUsers()
    } catch (e) {
      console.error("[OnlineUsers] Failed to add mock user", e)
    }
  }

  // Improved event handling
  const handleUserChangeEvent = useCallback((event: Event) => {
    handleUserChange(event as CustomEvent);
  }, []);

  // Storage event handler
  const handleStorageEvent = useCallback((e: StorageEvent) => {
    if (e.key === ONLINE_USERS_STORAGE_KEY) {
      console.log('[OnlineUsers] Storage event detected, updating users list');
      updateOnlineUsers();
    }
  }, []);

  useEffect(() => {
    // Initialize localStorage if it doesn't exist
    if (!localStorage.getItem(ONLINE_USERS_STORAGE_KEY)) {
      localStorage.setItem(ONLINE_USERS_STORAGE_KEY, "{}")
    }
    
    // Initial update
    updateOnlineUsers()

    // Set up interval to check every second
    intervalRef.current = setInterval(updateOnlineUsers, LOCAL_STORAGE_CHECK_INTERVAL)

    // Add event listener for user changes
    window.addEventListener('onlineUsersChanged', handleUserChangeEvent);

    // For debugging - listen to storage events directly
    window.addEventListener('storage', handleStorageEvent);

    return () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current)
      }
      // Remove event listeners
      window.removeEventListener('onlineUsersChanged', handleUserChangeEvent);
      window.removeEventListener('storage', handleStorageEvent);
    }
  }, [])

  // Handle manual refresh
  const handleManualRefresh = () => {
    updateOnlineUsers()
  }

  // Render based on state
  if (loading) {
    return (
      <div className="bg-white win95-inset p-1 h-40 overflow-y-auto text-sm">
        <div className="flex justify-center items-center h-full">
          <div className="text-center">
            <div
              className="win95-border bg-[#c0c0c0] p-1 mb-2 mx-auto"
              style={{ width: "20px", height: "20px" }}
            >
              <div className="animate-pulse w-full h-full bg-[#000080]"></div>
            </div>
            <span>Loading users...</span>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className="bg-white win95-inset p-1 h-40 overflow-y-auto text-sm">
      <div className="flex justify-between items-center mb-2">
        <div className="text-xs font-bold">Online Users ({users.length})</div>
        <div className="flex space-x-1">
          <button 
            onClick={handleManualRefresh} 
            className="win95-button bg-[#c0c0c0] px-1 py-0 text-xs"
            title="Refresh user list"
          >
            ↻
          </button>
          {/* Debug button - only in development */}
          {process.env.NODE_ENV === 'development' && (
            <button 
              onClick={addMockUser} 
              className="win95-button bg-[#c0c0c0] px-1 py-0 text-xs"
              title="Add test user (debug)"
            >
              +
            </button>
          )}
        </div>
      </div>

      {users.length === 0 ? (
        <div className="text-gray-500 py-2">No users online</div>
      ) : (
        <div>
          {users.map((user) => (
            <div key={user.id} className="flex items-center mb-1 py-1 px-1 hover:bg-[#efefef]">
              <div className="w-2 h-2 bg-green-500 mr-1 rounded-full flex-shrink-0"></div>
              <div className="flex flex-col">
                <span className="text-xs">{user.nickname}</span>
                <span className="text-xs text-gray-500 truncate" style={{ fontSize: "9px" }}>
                  ID: {user.id.substring(0, 10)}...
                </span>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  )
}